﻿using System;
using System.IO;
using System.Linq;
using System.ServiceModel;
using System.Web;
using SecurityClient;

namespace SecurityModule.Workflows
{
    class WFPostHomeYubikeyResetAction : SimpleWorkflow
    {
        public WFPostHomeYubikeyResetAction()
        {
            Verb = "POST";
            Path = "/Home/YubikeyResetAction";
        }
        public override void PreProcessImplementation(HttpContext context)
        {
            // verify token, activate and add Email and ClientCode to Request.Form
            var callback = new Func<string, string>(formFields =>
            {
                var fields = HttpUtility.ParseQueryString(formFields);

                //Read fields
                var tokenId = fields["Token"];
                var action = fields["Action"];
                try
                {
                    var security = new SecurityServiceProxy();
                    switch (action)
                    {
                        case "Approve":
                            var result = security.ApproveYubikeyReset(tokenId);

                            if (result.Success)
                            {
                                //Store transactionId for later commit.
                                context.Items["TransactionId"] = result.TransactionId;
                            }
                            else
                            {
                                //Bubble up an error to the application
                                fields.Add("EXTERRMSG", result.ErrorMessage);
                            }
                            break;
                        case "Disapprove":
                            // ignore it!
                            break;
                    }
                }
                catch (Exception exception)
                {
                    if (exception is PipeException || exception is EndpointNotFoundException)
                    {
                        //If the security service is offline or broken
                        if (fields.AllKeys.Contains("EXTERRMSG"))
                        {
                            fields["EXTERRMSG"] = SecurityServiceDownMsg;
                        }
                        else
                        {
                            fields.Add("EXTERRMSG", SecurityServiceDownMsg);
                        }
                    }
                    else
                    {
                        if (fields.AllKeys.Contains("EXTERRMSG"))
                        {
                            fields["EXTERRMSG"] = exception.Message;
                        }
                        else
                        {
                            fields.Add("EXTERRMSG", exception.Message);
                        }
                    }
                }
                return fields.ToString();
            });
            context.Request.Filter = new RequestFilter(context.Request.Filter, context.Request.ContentEncoding, callback);
        }

        public override void PostProcessImplementation(HttpContext context)
        {
            if (context.Response.StatusCode != 200 && context.Response.StatusCode != 302) return;
            var transactionId = context.Items["TransactionId"];
            if (transactionId == null) return;
            try
            {
                var security = new SecurityServiceProxy();
                security.Commit((Guid)transactionId);
            }
            // ReSharper disable EmptyGeneralCatchClause
            catch
            // ReSharper restore EmptyGeneralCatchClause
            {
                //If the security service is offline or broken then swallow the exception
            }
        }
    }
}
